using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Book.Blog.Core.Entities;
using Book.Blog.Core.Entities.Statistics;
using Book.Blog.Core.Entities.Settings;

namespace Book.Blog.Infrastructure.Data
{
    public class BlogDbContext : IdentityDbContext<User, IdentityRole<Guid>, Guid>
    {
        public BlogDbContext(DbContextOptions<BlogDbContext> options) : base(options)
        {
        }

        public DbSet<Post> Posts { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Tag> Tags { get; set; }
        public DbSet<Comment> Comments { get; set; }
        public DbSet<PostHistory> PostHistories { get; set; }
        public DbSet<PageView> PageViews { get; set; }
        public DbSet<UserAction> UserActions { get; set; }
        public DbSet<DailyStatistics> DailyStatistics { get; set; }
        public DbSet<SystemSetting> Settings { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            // User relationships
            builder.Entity<User>()
                .HasMany(u => u.Posts)
                .WithOne(p => p.Author)
                .HasForeignKey(p => p.AuthorId)
                .OnDelete(DeleteBehavior.Restrict);

            builder.Entity<User>()
                .HasMany(u => u.Comments)
                .WithOne(c => c.Author)
                .HasForeignKey(c => c.AuthorId)
                .OnDelete(DeleteBehavior.Restrict);

            builder.Entity<User>()
                .HasMany(u => u.Followers)
                .WithMany(u => u.Following)
                .UsingEntity(j => j.ToTable("UserFollowers"));

            // Post relationships
            builder.Entity<Post>()
                .HasMany(p => p.Tags)
                .WithMany(t => t.Posts)
                .UsingEntity(j => j.ToTable("PostTags"));

            builder.Entity<Post>()
                .HasOne(p => p.Category)
                .WithMany(c => c.Posts)
                .HasForeignKey(p => p.CategoryId)
                .OnDelete(DeleteBehavior.Restrict);

            // Soft delete filter
            builder.Entity<Post>().HasQueryFilter(e => !e.IsDeleted);
            builder.Entity<Category>().HasQueryFilter(e => !e.IsDeleted);
            builder.Entity<Tag>().HasQueryFilter(e => !e.IsDeleted);
            builder.Entity<Comment>().HasQueryFilter(e => !e.IsDeleted);
            builder.Entity<User>().HasQueryFilter(e => !e.IsDeleted);

            // Audit properties
            foreach (var entityType in builder.Model.GetEntityTypes())
            {
                if (typeof(IBaseEntity).IsAssignableFrom(entityType.ClrType))
                {
                    builder.Entity(entityType.ClrType)
                        .Property(nameof(IBaseEntity.CreatedAt))
                        .IsRequired();

                    builder.Entity(entityType.ClrType)
                        .Property(nameof(IBaseEntity.UpdatedAt))
                        .IsRequired(false);
                }
            }
        }

        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            foreach (var entry in ChangeTracker.Entries<IBaseEntity>())
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entry.Entity.CreatedAt = DateTime.UtcNow;
                        break;
                    case EntityState.Modified:
                        entry.Entity.UpdatedAt = DateTime.UtcNow;
                        break;
                }
            }

            return base.SaveChangesAsync(cancellationToken);
        }
    }
} 